﻿using System;
using System.Collections.Generic;
using System.Linq;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.Extensions;
using System.ComponentModel.DataAnnotations;
using HengTong.Model.Db.Hr;
using HengTong.Model.Extension;
using TiaoTaoHelper.Wtm.Models;


namespace HengTong.ViewModel.Person.SysPersonVms
{
    public partial class SysPersonListVm : BasePagedListVM<SysPersonView, SysPersonSearcher>
    {
        protected override IEnumerable<IGridColumn<SysPersonView>> InitGridHeader()
        {
            return new List<GridColumn<SysPersonView>>
            {
                this.MakeGridHeader(x => x.Name),
                this.MakeGridHeader(x => x.StaffNo),
                this.MakeGridHeader(x => x.BirthDate),
                this.MakeGridHeader(x => x.Age),
                this.MakeGridHeader(x => x.IsVeteran),
                this.MakeGridHeader(x => x.Order),
                this.MakeGridHeader(x => x.WorkYears),
                this.MakeGridHeader(x => x.CompanyYears),
                this.MakeGridHeader(x => x.Gender),
                this.MakeGridHeader(x => x.Ethnicity),
                this.MakeGridHeader(x => x.HighestEducation),
                this.MakeGridHeader(x => x.MaritalStatus),
                this.MakeGridHeader(x => x.FertilityStatus),
                this.MakeGridHeader(x => x.MajorCategory),
                this.MakeGridHeader(x => x.MajorName),
                this.MakeGridHeader(x => x.PhotoId).SetFormat(PhotoIdFormat),
                this.MakeGridHeader(x => x.IdCardNo),
                this.MakeGridHeader(x => x.IdCardFrontPhotoId).SetFormat(IdCardFrontPhotoIdFormat),
                this.MakeGridHeader(x => x.IdCardBackPhotoId).SetFormat(IdCardBackPhotoIdFormat),
                this.MakeGridHeader(x => x.HouseholdRegistration),
                this.MakeGridHeader(x => x.NativePlace),
                this.MakeGridHeader(x => x.PoliticalStatus),
                this.MakeGridHeader(x => x.PartyJoinDate),
                this.MakeGridHeader(x => x.PartyBranch),
                this.MakeGridHeader(x => x.ArchiveLocation),
                this.MakeGridHeader(x => x.ArchiveNo),
                this.MakeGridHeader(x => x.ArchiveTransferOutDate),
                this.MakeGridHeader(x => x.ArchiveTransferInDate),
                this.MakeGridHeader(x => x.HomeAddress),
                this.MakeGridHeader(x => x.Phone),
                this.MakeGridHeader(x => x.Email),
                this.MakeGridHeader(x => x.SalaryBank),
                this.MakeGridHeader(x => x.SalaryAccount),
                this.MakeGridHeader(x => x.BonusBank),
                this.MakeGridHeader(x => x.BonusAccount),
                this.MakeGridHeader(x => x.OrgId),
                this.MakeGridHeader(x => x.OrgName),
                this.MakeGridHeader(x => x.GroupId),
                this.MakeGridHeader(x => x.GroupName),
                this.MakeGridHeader(x => x.JobPositionName),
                this.MakeGridHeader(x => x.ResumeId).SetFormat(ResumeIdFormat),
                this.MakeGridHeader(x => x.HireDate),
                this.MakeGridHeader(x => x.ConfirmationDate),
                this.MakeGridHeader(x => x.EmploymentType),
                this.MakeGridHeader(x => x.ContractType),
                this.MakeGridHeader(x => x.ContractNo),
                this.MakeGridHeader(x => x.ContractStartDate),
                this.MakeGridHeader(x => x.ContractEndDate),
                this.MakeGridHeader(x => x.ResignationDate),
                this.MakeGridHeader(x => x.ResignationReason),
                this.MakeGridHeader(x => x.ResignationType),
                this.MakeGridHeader(x => x.State),
                this.MakeGridHeader(x => x.BloodType),
                this.MakeGridHeader(x => x.Hobbies),
                this.MakeGridHeaderAction(width: 200)
            };
        }

        private List<ColumnFormatInfo> PhotoIdFormat(SysPersonView entity, object val)
        {
            return new List<ColumnFormatInfo>
            {
                ColumnFormatInfo.MakeDownloadButton(ButtonTypesEnum.Button, entity.PhotoId),
                ColumnFormatInfo.MakeViewButton(ButtonTypesEnum.Button, entity.PhotoId, 640, 480),
            };
        }

        private List<ColumnFormatInfo> IdCardFrontPhotoIdFormat(SysPersonView entity, object val)
        {
            return new List<ColumnFormatInfo>
            {
                ColumnFormatInfo.MakeDownloadButton(ButtonTypesEnum.Button, entity.IdCardFrontPhotoId),
                ColumnFormatInfo.MakeViewButton(ButtonTypesEnum.Button, entity.IdCardFrontPhotoId, 640, 480),
            };
        }

        private List<ColumnFormatInfo> IdCardBackPhotoIdFormat(SysPersonView entity, object val)
        {
            return new List<ColumnFormatInfo>
            {
                ColumnFormatInfo.MakeDownloadButton(ButtonTypesEnum.Button, entity.IdCardBackPhotoId),
                ColumnFormatInfo.MakeViewButton(ButtonTypesEnum.Button, entity.IdCardBackPhotoId, 640, 480),
            };
        }

        private List<ColumnFormatInfo> ResumeIdFormat(SysPersonView entity, object val)
        {
            return new List<ColumnFormatInfo>
            {
                ColumnFormatInfo.MakeDownloadButton(ButtonTypesEnum.Button, entity.ResumeId),
                ColumnFormatInfo.MakeViewButton(ButtonTypesEnum.Button, entity.ResumeId, 640, 480),
            };
        }


        public override IOrderedQueryable<SysPersonView> GetSearchQuery()
        {
            var query = DC.Set<SysPerson>().AsQueryable();
            query = query
                .Where(x => x.GetType() == typeof(SysPerson))
                .CheckContain(Searcher.Name, x => x.Name)
                .CheckContain(Searcher.StaffNo, x => x.StaffNo)
                .CheckBetween(Searcher.BirthDate?.GetStartTime(), Searcher.BirthDate?.GetEndTime(), x => x.BirthDate,
                    includeMax: false)
                .CheckEqual(Searcher.Age, x => x.Age)
                .CheckEqual(Searcher.WorkYears, x => x.WorkYears)
                .CheckEqual(Searcher.CompanyYears, x => x.CompanyYears)
                .CheckBetween(Searcher.AgeStart, Searcher.AgeEnd, x => x.Age, includeMax: true) // 年龄区间
                .CheckBetween(Searcher.WorkYearsStart, Searcher.WorkYearsEnd, x => x.WorkYears,
                    includeMax: true) // 工龄区间
                .CheckBetween(Searcher.CompanyYearsStart, Searcher.CompanyYearsEnd, x => x.CompanyYears,
                    includeMax: true) // 司龄区间
                .CheckEqual(Searcher.IsVeteran, x => x.IsVeteran)
                .CheckEqual(Searcher.Order, x => x.Order)
                .CheckEqual(Searcher.Gender, x => x.Gender)
                .CheckEqual(Searcher.Ethnicity, x => x.Ethnicity)
                .CheckEqual(Searcher.HighestEducation, x => x.HighestEducation)
                .CheckEqual(Searcher.MaritalStatus, x => x.MaritalStatus)
                .CheckEqual(Searcher.FertilityStatus, x => x.FertilityStatus)
                .CheckEqual(Searcher.MajorCategory, x => x.MajorCategory)
                .CheckEqual(Searcher.MajorName, x => x.MajorName)
                .CheckContain(Searcher.IdCardNo, x => x.IdCardNo)
                .CheckContain(Searcher.HouseholdRegistration, x => x.HouseholdRegistration)
                .CheckContain(Searcher.NativePlace, x => x.NativePlace)
                .CheckEqual(Searcher.PoliticalStatus, x => x.PoliticalStatus)
                .CheckContain(Searcher.ArchiveLocation, x => x.ArchiveLocation)
                .CheckContain(Searcher.HomeAddress, x => x.HomeAddress)
                .CheckContain(Searcher.Phone, x => x.Phone)
                .CheckEqual(Searcher.OrgId, x => x.OrgId)
                .CheckEqual(Searcher.JobPositionId, x => x.JobPositionId)
                .CheckBetween(Searcher.HireDate?.GetStartTime(), Searcher.HireDate?.GetEndTime(), x => x.HireDate,
                    includeMax: false)
                .CheckEqual(Searcher.EmploymentType, x => x.EmploymentType)
                .CheckEqual(Searcher.ContractType, x => x.ContractType)
                .CheckContain(Searcher.ContractNo, x => x.ContractNo)
                .CheckEqual(Searcher.State, x => x.State)
                .Where(x => Searcher.States == null || !Searcher.States.Any() ||
                            (x.State.HasValue && Searcher.States.Contains(x.State.Value)))
                .CheckEqual(Searcher.BloodType, x => x.BloodType)
                .CheckDataPrivilege(Wtm);

            // 优化部门查询：查询指定部门及其子部门
            if (Searcher.GroupId.HasValue)
            {
                var targetGroup = DC.Set<SysGroup>().FirstOrDefault(g => g.ID == Searcher.GroupId.Value);
                if (targetGroup != null)
                {
                    // 获取目标部门及其所有子部门的ID
                    var groupIds = DC.Set<SysGroup>()
                        .Where(g => g.GroupCode.StartsWith(targetGroup.GroupCode))
                        .Select(g => g.ID)
                        .ToList();

                    query = query.Where(x => groupIds.Contains(x.GroupId.Value));
                }
            }

            return query.Select(x => new SysPersonView
                {
                    ID = x.ID,
                    Name = x.Name,
                    StaffNo = x.StaffNo,
                    BirthDate = x.BirthDate,
                    Age = x.Age,
                    IsVeteran = x.IsVeteran,
                    Order = x.Order,
                    WorkYears = x.WorkYears,
                    CompanyYears = x.CompanyYears,
                    Gender = x.Gender,
                    Ethnicity = x.Ethnicity,
                    HighestEducation = x.HighestEducation,
                    MaritalStatus = x.MaritalStatus,
                    FertilityStatus = x.FertilityStatus,
                    MajorCategory = x.MajorCategory,
                    MajorName = x.MajorName,
                    PhotoId = x.PhotoId,
                    IdCardNo = x.IdCardNo,
                    IdCardFrontPhotoId = x.IdCardFrontPhotoId,
                    IdCardBackPhotoId = x.IdCardBackPhotoId,
                    HouseholdRegistration = x.HouseholdRegistration,
                    NativePlace = x.NativePlace,
                    PoliticalStatus = x.PoliticalStatus,
                    PartyJoinDate = x.PartyJoinDate,
                    PartyBranch = x.PartyBranch,
                    ArchiveLocation = x.ArchiveLocation,
                    ArchiveNo = x.ArchiveNo,
                    ArchiveTransferOutDate = x.ArchiveTransferOutDate,
                    ArchiveTransferInDate = x.ArchiveTransferInDate,
                    HomeAddress = x.HomeAddress,
                    Phone = x.Phone,
                    Email = x.Email,
                    SalaryBank = x.SalaryBank,
                    SalaryAccount = x.SalaryAccount,
                    BonusBank = x.BonusBank,
                    BonusAccount = x.BonusAccount,
                    OrgName = x.Org.Name,
                    OrgId = x.OrgId,
                    GroupName = x.Group.GroupName,
                    GroupId = x.GroupId,
                    JobPositionName = x.JobPosition.Name,
                    ResumeId = x.ResumeId,
                    HireDate = x.HireDate,
                    ConfirmationDate = x.ConfirmationDate,
                    EmploymentType = x.EmploymentType,
                    ContractType = x.ContractType,
                    ContractNo = x.ContractNo,
                    ContractStartDate = x.ContractStartDate,
                    ContractEndDate = x.ContractEndDate,
                    ResignationDate = x.ResignationDate,
                    ResignationReason = x.ResignationReason,
                    ResignationType = x.ResignationType,
                    State = x.State,
                    BloodType = x.BloodType,
                    Hobbies = x.Hobbies,
                })
                .OrderBy(x => x.Order ?? 0)
                .ThenBy(x => x.StaffNo);
        }
    }

    public class SysPersonView : SysPerson
    {
        [Display(Name = "组织名称")] public String OrgName { get; set; }
        [Display(Name = "_Admin.GroupName")] public String GroupName { get; set; }
        [Display(Name = "岗位名称")] public String JobPositionName { get; set; }
    }
}